import pymysql


class SpiderscrapyPipeline:
    def process_item(self, item, spider):
        return item


class CnBlogsPipeline:
    def open_spider(self, spider):
        """
        每次启动爬虫项目会触发一次
        不是 每一次提交 item 一次
        可以放数据库的创建连接
        可以放文件的打开
        :param spider:
        :return:
        """
        print('爬虫项目启动成功 :>>>>>>>', spider)
        # 将打开文件的句柄初始化成类的参数
        # self.fp = open("./blog_pipline.json", "a", encoding="utf8")
        # 建立数据库连接
        self.conn = pymysql.connect(
            host="localhost", user="root", password="dyl20011113", database="sprider-test",
            charset="utf8", port=3306
        )
        # 创建游标对象
        self.cursor = self.conn.cursor()

    def close_spider(self, spider):
        """
        每次关闭爬虫项目会启动一次
        # 可以放数据库的关闭
        可以放文件的关闭
        :param spider:
        :return:
        """
        print('爬虫项目结束 :>>>>>>>>>>', spider)
        # 提交事务
        if hasattr(self, 'conn'):
            self.conn.commit()
        # 关闭游标
        if hasattr(self, 'cursor'):
            self.cursor.close()
        # 关闭数据库连接
        if hasattr(self, 'conn'):
            self.conn.close()

    def process_item(self, item, spider):
        """
        处理每一条爬取到的数据，将数据插入数据库
        :param item: 爬取到的数据项
        :param spider: 爬虫对象
        :return: item
        """
        try:
            # SQL插入语句
            sql = """
                INSERT INTO cnblogs_articles
                (title, detail_url, `desc`, author_name, author_blog, comment_num, up_num, visit_num, article_content)
                VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
            """
            # 处理数字字段，将字符串转为整数，如果为空则设为0
            comment_num = int(item.get('comment_num', 0) or 0)
            up_num = int(item.get('up_num', 0) or 0)
            visit_num = int(item.get('visit_num', 0) or 0)

            # 执行SQL语句
            self.cursor.execute(sql, (
                item.get('title', ''),
                item.get('detail_url', ''),
                item.get('desc', ''),
                item.get('author_name', ''),
                item.get('author_blog', ''),
                comment_num,
                up_num,
                visit_num,
                item.get("content", '')
            ))
            # 每插入一条数据就提交一次（也可以在close_spider中统一提交）
            self.conn.commit()
            print(f"✓ 成功插入: {item.get('title', '')}")
        except Exception as e:
            print(f"✗ 插入数据失败: {e}")
            print(f"  标题: {item.get('title', '')}")
            # 发生错误时回滚
            self.conn.rollback()
